package cn.zaichi.edu.excelcommon.utils;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import cn.zaichi.edu.excelcommon.annotations.ExcelDynamicTitle;
import cn.zaichi.edu.excelcommon.annotations.ExcelField;
import cn.zaichi.edu.excelcommon.entity.BaseExportParam;
import cn.zaichi.edu.excelcommon.entity.ExportTitleEntity;
import cn.zaichi.edu.excelcommon.entity.ImportTitleEntity;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;

public class ExportTitleUtil {


    /**
     * 根据模板获取表头（获取最终级表头）
     * @return
     */
    public static List<ExportTitleEntity> getTempTilteList(Workbook hssfWorkbook, List<CellRangeAddress> combineCell, int startRow, int endRow, int startCell){
        List<ExportTitleEntity> titleEntityList = new ArrayList<>();
        List<ImportTitleEntity> excelTitle = ImportTitleUtil.readExcelTitle(hssfWorkbook, combineCell, startRow, endRow, startCell);
        List<ImportTitleEntity> lastTitle = ImportTitleUtil.getLastTitle(excelTitle);
        lastTitle.forEach(title->{
            ExportTitleEntity exportTitleEntity=new ExportTitleEntity();
            exportTitleEntity.setTitleName(title.getName());
            exportTitleEntity.setTitleSort(title.getCell());
            titleEntityList.add(exportTitleEntity);
        });
        return titleEntityList;
    }

    /**
     * 获取最终表头
     * @param titleList
     * @return
     */
    public static List<ExportTitleEntity> getLastTitle(List<ExportTitleEntity> titleList){
        return titleList.stream().filter(e->e.getChildrens()==null||e.getChildrens().size()==0).collect(Collectors.toList());
    }


    /**
     * 根据map 获取表头
     * @param map
     * @return
     */
    public static List<ExportTitleEntity> getMapTitleList(Map<String,Object> map){
        List<ExportTitleEntity> titleList=new ArrayList<>();
        int i=0;
        for (String titleName : map.keySet()) {
            ExportTitleEntity titleEntity=new ExportTitleEntity();
            titleEntity.setRowNum(0);
            titleEntity.setTitleSort(i);
            titleEntity.setTitleName(titleName);
            titleList.add(titleEntity);
            i++;
        }
        return titleList;
    }

    /**
     * 解析表头
     * 最终级不能合并列
     * 过于复杂的表头推荐使用模板导出
     * @param titleList
     * @return
     */
    public static List<ExportTitleEntity> getTitleList(List<ExportTitleEntity> titleList,ExportTitleEntity parent){
        int cellNum=0;
        for (ExportTitleEntity title : titleList) {
            title.setTitleSort(title.getTitleSort()+cellNum);
            title.setParent(parent);
            if(title.getChildrens()!=null&&title.getChildrens().size()>0){
                //合并列
                title.setRegionCell(title.getChildrens().size());
                cellNum+=title.getChildrens().size()-1;
                getTitleList(title.getChildrens(),title);
            }
        }
        return titleList;
    }

    /**
     * 根据字段注解获取表头
     * @param fields
     * @return
     */
    public static List<ExportTitleEntity> getBeanTitleList(Field[] fields,List<?> dataList) throws IllegalAccessException {
        List<ExportTitleEntity> list=new ArrayList<>();
        for (Field field : fields) {
            ExcelField fieldAnnotation = field.getAnnotation(ExcelField.class);
            if (fieldAnnotation != null) {
                if (fieldAnnotation.title() != null && fieldAnnotation.title() != ""&&fieldAnnotation.sort()>-1) {
                    ExportTitleEntity titleVo = new ExportTitleEntity();
                    titleVo.setTitleSort(fieldAnnotation.sort());
                    titleVo.setTitleName(fieldAnnotation.title());
                    list.add(titleVo);

                }
            }
        }

        if(list.size()>0){
            list.sort(((o1, o2) -> o1.getTitleSort()-o2.getTitleSort()));
        }
        //最大排序号
        int maxSort=list.size();
        //动态列
        List<ExportTitleEntity> dynamicTitleList=getDynamicTitle(fields,maxSort,dataList);
        list.addAll(dynamicTitleList);
        return list;
    }


    /**
     * 根据字段字段获取动态列
     * @param fields
     * @param sort
     * @return
     */
    private static List<ExportTitleEntity> getDynamicTitle(Field[] fields,int sort,List<?> dataList) throws IllegalAccessException {
        for (Field field : fields) {
            field.setAccessible(true);
            ExcelField fieldAnnotation = field.getAnnotation(ExcelField.class);
            //动态列标识
            if (fieldAnnotation != null && fieldAnnotation.dynamic()) {
                String flage = fieldAnnotation.splitFlage();
                if (field.getType() != List.class) {
                    continue;
                }
                Type genericType = field.getGenericType();
                if (genericType == null) {
                    continue;
                }

                if (genericType instanceof ParameterizedType) {
                    ParameterizedType pt = (ParameterizedType) genericType;
                    Class<?> genericClz = (Class<?>) pt.getActualTypeArguments()[0];
                    if (!genericClz.getPackage().getName().startsWith("cn.zaichi.edu.")) {
                        continue;
                    }
                    Field[] dynamicFields = genericClz.getDeclaredFields();
                    return getDynamicTitleByDeclaredFields(field,dynamicFields,sort,dataList);
                }
            }
        }
        return new ArrayList<>();
    }

    /**
     * 获取动态列的值
     * @param field  实体动态列字段
     * @param fields 关联实体的字段列表
     * @param sort   排序
     * @param dataList 数据
     * @return
     * @throws IllegalAccessException
     */
    private static List<ExportTitleEntity> getDynamicTitleByDeclaredFields(Field field,Field[] fields,int sort,List<?> dataList) throws IllegalAccessException {
        List<ExportTitleEntity> list=new ArrayList<>();
        for (Field dynamicField : fields) {
            dynamicField.setAccessible(true);
            ExcelDynamicTitle dynamicTitleAnnotation = dynamicField.getAnnotation(ExcelDynamicTitle.class);
            if (dynamicTitleAnnotation != null) {
                //获取动态列的值
                List<?> dyList = (List<?>) field.get(dataList.get(0));
                for (Object o : dyList) {
                    String titleName = dynamicField.get(o) == null ? "" : dynamicField.get(o).toString();
                    ExportTitleEntity titleVo = new ExportTitleEntity();
                    titleVo.setTitleSort(sort);
                    titleVo.setTitleName(titleName);
                    list.add(titleVo);
                    sort++;
                }


            }
        }
        return list;
    }


    /**
     * 设置表头
     */
    public static void setSheetTitle(int rowNum,List<ExportTitleEntity> list,HSSFSheet sheet,BaseExportParam param,Workbook workbook){
        //创建表头行
        HSSFRow rowTitle = sheet.getRow(rowNum)==null?sheet.createRow(rowNum):sheet.getRow(rowNum);
        for (ExportTitleEntity titleEntity : list) {
            rowNum=param.getTitleStarRow();
            int cellNum=titleEntity.getParent()==null?param.getStartColumn()+titleEntity.getTitleSort():titleEntity.getParent().getTitleSort()+param.getStartColumn()+titleEntity.getTitleSort();
            HSSFCell cell = rowTitle.createCell(cellNum);
            cell.setCellValue(new HSSFRichTextString(titleEntity.getTitleName()));
            //设置样式
            if(param.getTempPath()==null){
                cell.setCellStyle( param.getTitleStyle().getTitleStyle((HSSFWorkbook) workbook));
            }
            sheet.setColumnWidth(param.getStartColumn()+titleEntity.getTitleSort(), titleEntity.getTitleName().getBytes().length * 2 * 256);// （中文适用）

            if(titleEntity.getChildrens()!=null&&titleEntity.getChildrens().size()>0){
                //合并列
                CellRangeAddress region = new CellRangeAddress(rowTitle.getRowNum(), rowTitle.getRowNum(), cellNum, cellNum+titleEntity.getChildrens().size()-1);
                sheet.addMergedRegion(region);

                setSheetTitle(++rowNum,titleEntity.getChildrens(),sheet,param,workbook);
            }
        }
    }

}
